# The PluginList class is an array, enhanced to allow access to loaded plugins
# by name, and iteration over loaded plugins in order of priority.
#
# Each loaded plugin has a corresponding Plugin instance within this array, and 
# the order the plugins were loaded is reflected in the entries in this array.
class PluginList < Array
  # Finds plugins with the given name or index.  For example,
  # 
  #   Rails.plugins[0]      # => The first plugin loaded
  #   Rails.plugins[:foo]   # => The "foo" plugin
  #   Rails.plugins['foo']  # => The "foo" plugin
  # 
  # This will return an instance of the +Plugin+ class.
  def [](name)
    if name.is_a?(String) || name.is_a?(Symbol)
      self.find {|plugin| plugin.name.to_s == name.to_s}
    else
      if name.is_a?(Integer)
        super
      end
    end
  end
  
  # Gets the plugins in the specified comma-delimited list.  If the list is
  # not specified (i.e. nil), then all plugins are returned.
  # 
  # If a specific plugin cannot be found, an exception will be raised indicating
  # so.
  def find_by_names(names = nil)
    if names
      plugins = names.split(',')
      missing_plugins = plugins - map(&:name)
      
      raise ArgumentError, "Couldn't find plugin(s): #{missing_plugins.to_sentence}" if missing_plugins.any?
      plugins.collect! {|name| self[name]}
    else
      plugins = self
    end
    
    plugins
  end
  
  # Iterates through each plugin by priority.  The last loaded plugin will
  # always have the highest priority.
  # 
  # Effectively, this is like +Rails.plugins.reverse+.  When given a block, it
  # behaves like +Rails.plugins.reverse.each+.
  def by_precedence(&block)
    if block_given?
      reverse.each { |x| yield x }
    else 
      reverse
    end
  end
end
